/* eslint-disable max-lines */
import { useStore } from '@/hooks';
import { Button, Dialog, Form, Select, Upload, Table, Input, Message } from '@alifd/next';
import React, { useEffect, useRef, useState } from 'react';
import { t } from '@lingui/macro';
import DrawerFooter from '@/components/DrawerFooter';
import { FieldsGrid, TitleGrid } from '../stores/definitions';
import { observer } from 'mobx-react-lite';
import { observable } from 'mobx';
import styles from './BusHot.module.scss';
import TauSimpleSelect from '@/components/TauSimpleSelect';

const FromItem = Form.Item;

const DataForm = ({ modal, xcxInfo, onCancel, onSubmit, handleCustomRequest }) => {
  const { xcxStore: store } = useStore();
  const editCtx = useRef({ origin: {}, changed: {} }).current; // 用于计算是否修改
  const [isViewMode] = useState(modal[0] === 'view');
  const formProps = isViewMode ? { field: false } : {};
  const [xcx] = useState(() => observable({}));
  const uploaderRef = useRef(null);
  const [idx, setIdx] = useState();
  const [state, setState] = useState([]);

  useEffect(() => { if (modal[1]?.startsWith?.('toClose') || modal[2]?.startsWith?.('toClose')) handleCancel(); }, [modal]);
  useEffect(() => {
    (async () => {
      await store.getIconUrl('entryLogo');
      if (JSON.stringify(xcxInfo) !== '{}') {
        const data = xcxInfo;
        editCtx.origin = _.cloneDeep(data);
        _.assign(xcx, data);
        const { entryType, type: changeLineType, startMainArea, endMainArea, extra, endMinorAreas, startMinorAreas } = data;
        if (extra) {
          const toggleExtra = Object.entries(extra).map(([itemId, content]) => ({ itemId, content }));
          for (const key in extra) {
            if (Object.hasOwnProperty.call(extra, key)) {
              const element = extra[key];
              if (key === 'iconUrl') {
                _.set(xcx, 'iconUrl', element);
              }
              if (key === 'lineType') {
                _.set(xcx, 'lineType', element);
              }
              if (key === 'jumpType') {
                _.set(xcx, 'jumpType', element);
              }
            }
          }
          setState(toggleExtra);
        }
        const type = entryType == '2' ? String(xcx.lineType) : changeLineType;
        await handleInitData(type, startMainArea, endMainArea, startMinorAreas, endMinorAreas);
      } else {
        _.set(xcx, 'sortWeight', 1);
        _.set(xcx, 'entryType', '0');
        _.set(xcx, 'enable', true);
        _.set(xcx, 'imgConfigs', []);
        _.set(xcx, 'subBusinessType', []);
        _.set(xcx, 'showPalace', []);
        _.set(xcx, 'appType', []);
        store.fromCity = [];
        store.toCity = [];
      }
    })();
    return () => {
      store.fromCity = [];
      store.toCity = [];
      store.startStation = [];
      store.showToStations = [];
    };
  }, []);

  // 城市联动
  useEffect(() => {
    (async () => {
      const { type: changeLineType, lineType, entryType } = xcx;
      const type = entryType == '2' ? String(lineType) : changeLineType;
      await handleEffectChange(type);
    })();
  }, [xcx.type, xcx.lineType]);

  if (!xcx) return <></>;

  async function handleInitData(type, startMainArea, endMainArea, startMinorAreas, endMinorAreas) {
    switch (type) {
      case '1':
      case '5':
        // 包车  需要考虑到城市不再的情况
        if (startMainArea) {
          const end = await store.getCcStation({ city: startMainArea, fromCity: startMainArea, priceType: 1 });
          store.endStation = end;
        }
        break;
      case '2':
        // 专线
        store.toCity = await store.getScCity({ fromCity: startMainArea });
        store.startStation = await store.getScStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '0', showToStations: endMinorAreas, priceType: 2 });
        store.endStation = await store.getScStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '1', showFromStations: startMinorAreas, priceType: 2 });
        break;
      case '3':
        store.toCity = await store.getBusCity({ fromCity: startMainArea });
        store.startStation = await store.getBusStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '0', showToStations: endMinorAreas, priceType: 3 });
        store.endStation = await store.getBusStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '1', showFromStations: startMinorAreas, priceType: 3 });
        break;
      case '4':
        store.toCity = await store.getRsCity({ fromCity: startMainArea });
        store.startStation = await store.getRsStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '0', showToStations: endMinorAreas, priceType: 4 });
        store.endStation = await store.getRsStation({ fromCities: [startMainArea], toCities: [endMainArea], direction: '1', showFromStations: startMinorAreas, priceType: 4 });
        break;
      default:
        break;
    }
  }

  async function handleEffectChange(type) {
    switch (type) {
      case '1':
      case '5':
        // eslint-disable-next-line no-case-declarations
        const city = await store.getCcCity({});
        store.fromCity = city;
        store.toCity = city;
        break;
      case '2':
        store.fromCity = await store.getScCity({});
        break;
      case '3':
        store.fromCity = await store.getBusCity({});
        break;
      case '4':
        store.fromCity = await store.getRsCity({});
        break;
      default:
        break;
    }
  }

  const customModel = {
    0: ['mainTitle', 'subTitle', 'type']
      .concat(xcx.type === '1' ? ['subType'] : [])
      .concat(['showPalace', 'startMainArea', 'endMainArea', 'startMinorAreas', 'endMinorAreas', 'iconName', 'appId', 'iconUrl', 'sortWeight']),
    1: ['hotRouteName', 'type'].concat(xcx.type === '1' ? ['subType'] : []).concat(['sortWeight', 'startMainArea', 'endMainArea', 'startMinorAreas', 'endMinorAreas']),
    2: ['mainTitle', 'subTitle', 'iconName', 'showPalace', 'link', 'subBusinessType', 'jumpType', 'lineType', 'startMainArea', 'endMainArea', 'startMinorAreas', 'endMinorAreas', 'sortWeight', 'imgConfigs'],
    undefined: [],
  };

  const columns = [
    {
      title: t`序号`,
      dataIndex: 'id',
      align: 'center',
      cell: (v, i) => <span>{i + 1}</span>,
    },
    {
      title: t`标识`,
      dataIndex: 'itemId',
      width: 300,
      align: 'center',
      cell: (v) => <Input onChange={handelChangeName} style={{ width: '100%' }} value={v} />,
    },
    {
      title: t`内容`,
      dataIndex: 'content',
      width: 400,
      align: 'center',
      cell: (v) => <Input onChange={handleChangeContent} style={{ width: '100%' }} value={v} />,
    },
    {
      title: t`操作`,
      dataIndex: 'name',
      align: 'center',
      cell: (v, i) => (
        <>
          <Button type="primary" text style={{ color: 'red' }} onClick={() => handleDeleteState(i)}>{t`删除`}</Button>
        </>
      ),
    },
  ];

  const overrideModel = {
    imgConfigs: {
      label: t`图片`,
      ui: {
        renderer: (r) => {
          const img = r?.map((item) => {
            if (item.originFileObj) {
              return item;
            }
            return ({
              uid: item.uid,
              state: 'done',
              name: item.name,
              type: item.type,
              url: `${API_BASE}/api/files/${item.uid}`,
              downloadURL: `${API_BASE}/api/files/${item.uid}`,
              imgURL: `${API_BASE}/api/files/${item.uid}`,
            });
          });
          return (
            <Upload.Card
              listType="card"
              className={styles.container}
              value={img}
              name="imgConfigs"
              autoUpload={false}
              beforeUpload={beforeUpload}
              headers={{ Authorization: `Bearer ${TOKEN}` }}
              data={(file) => {
                return { binaryId: file.uid, mimeType: file.type };
              }}
              onPreview={handlePreview}
              ref={saveUploaderRef}
              formatter={(res, files) => {
                return {
                  uid: files.uid,
                  name: files.name,
                  state: 'done',
                  type: files.type,
                  url: `${API_BASE}/api/files/${files.uid}`,
                  downloadURL: `${API_BASE}/api/files/${files.uid}`,
                  imgURL: `${API_BASE}/api/files/${files.uid}`,
                };
              }}
              useDataURL
              request={customRequest}
              action={`${API_BASE}/upload`}
              accept="image/png, image/jpg, image/jpeg, image/gif, image/bmp, image/webp"
            />
          );
        },
        span: 4,
      },
    },
    startMainArea: {
      label: t`开始城市`,
      ui: {
        renderer: (v) => <TauSimpleSelect hasClear value={v || ''} dataSource={store.fromCity} />,
        itemProps: {
          required: xcx?.entryType === '1',
        },
      },
    },
    endMainArea: {
      label: t`结束城市`,
      ui: {
        renderer: (v) => <TauSimpleSelect hasClear value={v || ''} dataSource={store.toCity} />,
        itemProps: {
          required: xcx?.entryType === '1',
        },
      },
    },
    startMinorAreas: {
      label: t`开始站点`,
      ui: {
        renderer: (v) => <Select hasClear mode="multiple" value={v || []} onChange={(_, __, l) => handleStartStation(l)} dataSource={store.startStation} />,
      },
    },
    endMinorAreas: {
      label: t`结束站点`,
      ui: {
        renderer: (v) => <Select hasClear mode="multiple" value={v || []} onChange={(_, __, l) => handleEndStation(l)} dataSource={store.endStation} />,
      },
    },
    sortWeight: {
      ui: {
        itemProps: {
          required: xcx?.entryType !== '2',
        },
      },
    },
    type: {
      label: t`线路类型`,
      ui: {
        itemProps: {
          required: xcx?.entryType === '1',
        },
      },
    },
    subType: {
      label: t`包车类型`,
      ui: {
        itemProps: { required: xcx?.type === '1' },
      },
    },
    showPalace: {
      label: t`展示位置`,
      ui: {
        itemProps: { required: xcx?.entryType === '1' },
      },
    },
    iconName: {
      label: t`icon名称`,
      ui: {
        itemProps: { required: xcx?.entryType === '1' },
      },
    },
    extras: {
      ui: {
        renderer: (__) => (
          <>
            <Button type="primary" style={{ marginBottom: 10 }} onClick={() => handleAddState()}>{t`添加属性`}</Button>
            <Table
              hasBorder={false}
              dataSource={state}
              columns={columns}
              onRowClick={(_, index) => setIdx(index)}
            />
          </>
        ),
        span: 4,
      },
    },
    iconUrl: {
      ui: {
        renderer: (v) => <TauSimpleSelect value={v} dataSource={store.iconUrls} />,
      },
    },
  };

  /**
   * @description 动态回现表单数据
   * @param {*} values
   * @param {*} item 数据Items
   */
  const handleChange = async (values, item) => {
    const { name, value } = item;
    _.set(xcx, name, value);
    const { type: changeLineType, lineType, entryType } = xcx;
    const type = entryType == '2' ? String(lineType) : changeLineType;
    // 如果是开始城市
    if (name === 'startMainArea') {
      await handleStartMainArea(type, value);
    }
    // 如果是结束城市
    if (name === 'endMainArea') {
      await handleEndMainArea(type, value);
    }
    // 如果是开始站点
    if (name === 'startMinorAreas') {
      handleStartMinorAreas(type, value);
    }
    // 如果是结束站点
    if (name === 'endMinorAreas') {
      handleEndMinorAreas(type, value);
    }
    if (name === 'type' || name === 'lineType' || name === 'entryType') {
      handleTypeChanges(name);
    }
    // eslint-disable-next-line eqeqeq
    editCtx.changed[name] = value == _.get(editCtx.origin, name) ? '' : value;
  };

  const handleStartMainArea = async (type, value) => {
    switch (type) {
      case '1':
      case '5':
        store.startStation = await store.getCcStation({ city: value, fromCity: value });
        break;
      case '2':
        store.toCity = [];
        store.startStation = [];
        store.endStation = [];
        resetXcxFields(['startMinorAreas', 'endMinorAreas', 'endMainArea']);
        store.toCity = await store.getScCity({ formCity: value });
        break;
      case '3':
        resetXcxFields(['startMinorAreas', 'endMinorAreas', 'endMainArea']);
        store.toCity = [];
        store.startStation = [];
        store.endStation = [];
        store.toCity = await store.getBusCity({ fromCity: value });
        break;
      case '4':
        store.toCity = [];
        store.startStation = [];
        store.endStation = [];
        store.toCity = await store.getRsCity({ fromCity: value });
        break;
      default:
        break;
    }
  };

  const handleEndMainArea = async (type, value) => {
    switch (type) {
      case '1':
      case '5':
        store.endStation = await store.getCcStation({ city: value, fromCity: value });
        break;
      case '2':
        store.startStation = await store.getScStation({ fromCities: [xcx.startMainArea], toCities: [value], direction: '0', priceType: 2 });
        break;
      case '3':
        store.startStation = await store.getBusStation({ fromCities: [xcx.startMainArea], toCities: [value], direction: '0', priceType: 3 });
        break;
      case '4':
        store.startStation = await store.getRsStation({ fromCities: [xcx.startMainArea], toCities: [value], direction: '0', priceType: 4 });
        break;
      default:
        break;
    }
  };

  const handleStartMinorAreas = async (type, value) => {
    if (value === undefined) {
      resetXcxFields(['startMinorAreas']);
      return;
    }
    switch (type) {
      case '2':
        store.endStation = await store.getScStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], direction: '1', priceType: 2 });
        break;
      case '3':
        store.endStation = await store.getBusStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], showFromStations: value, direction: '1', priceType: 3 });
        break;
      case '4':
        store.endStation = await store.getRsStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], showFromStations: value, direction: '1', priceType: 4 });
        break;
      default:
        break;
    }
  };

  const handleEndMinorAreas = async (type, value) => {
    if (value === undefined) {
      resetXcxFields(['endMinorAreas']);
      return;
    }
    switch (type) {
      case '2':
        store.startStation = await store.getScStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], showToStations: value, direction: '0', priceType: 2 });
        break;
      case '3':
        store.startStation = await store.getBusStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], showToStations: value, direction: '0', priceType: 3 });
        break;
      case '4':
        store.startStation = await store.getRsStation({ fromCities: [xcx.startMainArea], toCities: [xcx.endMainArea], showToStations: value, direction: '0', priceType: 4 });
        break;
      default:
        break;
    }
  };

  // 重置 xcx 的字段
  const resetXcxFields = (fields) => {
    fields.forEach((field) => _.set(xcx, field, ''));
  };

  // 处理类型变化
  const handleTypeChanges = (name) => {
    resetXcxFields(['startMainArea', 'endMainArea', 'startMainAreaText', 'endMainAreaText', 'startMinorAreasText', 'endMinorAreasText']);
    _.set(xcx, 'startMinorAreas', []);
    _.set(xcx, 'endMinorAreas', []);

    if (name === 'entryType') {
      resetXcxFields(['lineType', 'type']);
    }
  };

  const handleAddState = () => {
    const data = {
      itemId: '',
      content: '',
    };
    setState((pre) => {
      const cloneData = [...pre];
      cloneData.push(data);
      return cloneData;
    });
  };

  const handelChangeName = (v) => {
    setState((pre) => {
      const toggle = [...pre];
      toggle[idx].itemId = v;
      return toggle;
    });
  };

  const handleChangeContent = (v) => {
    setState((pre) => {
      const toggle = [...pre];
      toggle[idx].content = v;
      return toggle;
    });
  };

  const handleDeleteState = (i) => {
    setState((pre) => {
      const arr = [...pre];
      arr.splice(i, 1);
      return arr;
    });
  };

  const handlePreview = ({ url }) => {
    Dialog.show({
      title: t`预览`,
      content: <img src={url} style={{ maxWidth: '800px', width: '100%', height: '100%', objectFit: 'cover' }} />,
      footer: false,
    });
  };

  const saveUploaderRef = (ref) => {
    if (ref) uploaderRef.current = ref.getInstance();
  };

  const beforeUpload = (info, options) => {
    return options;
  };

  const customRequest = (data) => {
    handleCustomRequest(data);
  };

  /**
   * 监听开始站点
   * @param {*} l 对象模型
   */
  const handleStartStation = (l) => {
    if (l) {
      _.set(xcx, 'startMinorAreasText', l.map((p) => p.label).join('、'));
    } else {
      _.set(xcx, 'startMinorAreasText', '');
      _.set(xcx, 'startMinorAreas', []);
    }
  };

  /**
   * 监听结束站点
   * @param {*} l 对象模型
   */
  const handleEndStation = (l) => {
    if (l) {
      _.set(xcx, 'endMinorAreasText', l.map((p) => p.label).join('、'));
    } else {
      _.set(xcx, 'endMinorAreasText', '');
      _.set(xcx, 'endStationId', '');
      _.set(xcx, 'endMinorAreas', []);
    }
  };

  /**
   * @description 提交表单实现修改车辆
   * @param {*} r formData
   */
  const handleSubmit = (values, errors) => {
    if (!_.isEmpty(errors)) {
      console.log(errors);
      return;
    }
    xcx.imgConfigs = xcx.imgConfigs?.map((item) => {
      return {
        uid: item.uid,
        name: item.name,
        type: item.type,
      };
    });

    const tempState = _.cloneDeep(state);

    const verifyState = tempState?.some((item) => item.itemId === '');
    if (verifyState) {
      return Message.error({ content: t`标识不能为空!` });
    }
    if (xcx.entryType == '0' && xcx.iconUrl) {
      store.updateOrAddItem(tempState, 'iconUrl', xcx.iconUrl);
    }
    if (xcx.entryType == '2' && (xcx.jumpType == 0 || xcx.jumpType == 1)) {
      store.updateOrAddItem(tempState, 'jumpType', xcx.jumpType);
    }
    if (xcx.entryType == '2' && xcx.lineType) {
      store.updateOrAddItem(tempState, 'lineType', xcx.lineType);
    }
    if (!xcx.startMinorAreas) {
      _.set(xcx, 'startMinorAreas', []);
    }
    if (!xcx.endMinorAreas) {
      _.set(xcx, 'endMinorAreas', []);
    }
    const toggleState = tempState?.reduce((acc, item) => {
      const { itemId, content } = item;
      acc[itemId] = content;
      return acc;
    }, {});
    _.set(xcx, 'extra', toggleState);
    onSubmit?.(xcx);
    uploaderRef.current && uploaderRef.current.startUpload();
  };

  const handleCancel = () => {
    // eslint-disable-next-line no-return-assign
    if (!_.isEmpty(_.transform(editCtx.changed, (r, v, k) => v !== undefined && (r[k] = v)))) {
      Dialog.confirm({
        content: t`放弃修改内容？`,
        onOk: () => onCancel?.(),
      });
      return;
    }
    onCancel?.();
  };

  return (
    <Form
      inline
      isPreview={isViewMode}
      {...formProps}
      value={xcx}
      onChange={handleChange}
      useLabelForErrorMessage
    >
      <TitleGrid title={t`基础信息`} />
      <FieldsGrid
        formData={xcx}
        mode={modal[0]}
        columns={4}
        overrideModel={overrideModel}
        fields={
          ['routeName', 'entryType', 'appType', 'enable']}
      />
      <TitleGrid title={t`入口信息`} />
      <FieldsGrid
        formData={xcx}
        mode={modal[0]}
        columns={4}
        overrideModel={overrideModel}
        fields={[].concat(customModel[xcx?.entryType])}
      />
      {xcx.entryType === '2' && (
        <div>
          <div><b>{t`图片比例说明: `}</b></div>
          <div><b>{t`1、拼车图片格式比例大小以 5:2 最佳`}</b></div>
          <div><b>{t`2、其他图片格式比例大小以 3:1 最佳`}</b></div>
        </div>)}
      <TitleGrid title={t`说明及其他`} />
      <FieldsGrid
        formData={xcx}
        mode={modal[0]}
        columns={4}
        overrideModel={overrideModel}
        fields={['extras', 'description']}
      />
      <DrawerFooter>
        <FromItem>
          {!isViewMode && <Form.Submit validate type="primary" onClick={handleSubmit}>{t`保存`}</Form.Submit>}
          <Button style={{ marginLeft: 8 }} onClick={handleCancel}>{t`取消`}</Button>
        </FromItem>
      </DrawerFooter>
    </Form>
  );
};

export default observer(DataForm);
